using System.Collections.Generic;

namespace TLang.Values.Primitives
{
    using Ast;

    public class Eq : PrimFun
    {
        public Eq() : base("=", 2)
        {
            
        }

        public static Value IsEq(List<Value> args, Node location)
        {
            Value v1 = args[0];
            Value v2 = args[1];
            if (v1 is IntValue v11 && v2 is IntValue v21)
            {
                return BoolValue.Of(v11.Value == v21.Value);
            }
            if (v1 is FloatValue lv && v2 is FloatValue rv)
            {
                return BoolValue.Of(lv.Value == rv.Value);
            }
            if (v1 is FloatValue fv1 && v2 is IntValue fv2)
            {
                return BoolValue.Of(fv1.Value == fv2.Value);
            }
            if (v1 is IntValue iv1 && v2 is FloatValue iv2)
            {
                return BoolValue.Of(iv1.Value == iv2.Value);
            }
            if (v1 is BoolValue bv1 && v2 is BoolValue bv2)
            {
                return BoolValue.Of(bv1.Value == bv2.Value);
            }
            if (v1 is StringValue sv1 && v2 is StringValue sv2)
            {
                return BoolValue.Of(sv1.Value == sv2.Value);
            }
            if (v1 is CharValue c1 && v2 is CharValue c2)
            {
                return BoolValue.Of(c1.Value == c2.Value);
            }
            if (v1.Type == TType.Void && v2.Type == TType.Void)
            {
                return BoolValue.True;
            }
            if (v1 is TType && v2 is TType)
            {
                return BoolValue.Of(v1 == v2);
            }

            throw Util.GeneralError(location, "incorrect argument types for =: " + v1 + ", " + v2);
        }

        public override Value Apply(List<Value> args, Node location)
        {
            return IsEq(args, location);
        }
    }
}